package com.gccloud.design.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gccloud.design.dao.StfBusinessTypeDao;
import com.gccloud.design.entity.StfBusinessTypeEntity;
import com.gccloud.design.feign.BwpOperDockingClient;
import com.gccloud.design.feign.DictClient;
import com.gccloud.design.service.IStfBusinessTypeService;
import com.gccloud.starter.common.exception.GlobalException;
import com.gccloud.starter.common.vo.R;
import com.gccloud.starter.core.dto.SysDictItemDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import com.gccloud.idc.common.utils.SnowflakeIdWorker;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @ClassName : StfBusinessTypeServiceImpl
 * @Author : sulei
 * @Date : 2021/01/08 15:29
 * @Description :
 */
@Service
public class StfBusinessTypeServiceImpl extends ServiceImpl<StfBusinessTypeDao, StfBusinessTypeEntity> implements IStfBusinessTypeService {

    private final SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(25, 25);

    @Resource
    private DictClient dictClient;

    @Resource
    private BwpOperDockingClient bwpOperDockingClient;

    /**
     * 修改业务类型
     *
     * @param stfBusinessTypeEntity
     */
    @Override
    public void update(StfBusinessTypeEntity stfBusinessTypeEntity) {
        checkRepeat(stfBusinessTypeEntity);
        StfBusinessTypeEntity entity = getByIdWithDp(stfBusinessTypeEntity.getId());
        stfBusinessTypeEntity.setTenantId(entity.getTenantId());
        updateByIdWithDp(stfBusinessTypeEntity);
        // 同步更新流程平台数据
        bwpOperDockingClient.saveUpdateBwpBusiType(JSONObject.toJSONString(stfBusinessTypeEntity));
    }

    /**
     * 新增业务类型
     *
     * @param stfBusinessTypeEntity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R add(StfBusinessTypeEntity stfBusinessTypeEntity) {
        if (stfBusinessTypeEntity.getCode() == null || "".equals(stfBusinessTypeEntity.getCode())) {
            // 场景名称校验
            LambdaQueryWrapper<StfBusinessTypeEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ne(StringUtils.isNotBlank(stfBusinessTypeEntity.getId()), StfBusinessTypeEntity::getId, stfBusinessTypeEntity.getId())
                    .eq(StfBusinessTypeEntity::getName, stfBusinessTypeEntity.getName());
            if (count(queryWrapper) > 0) {
                return R.error("场景名称已存在，请重新输入名称");
            }
            // 场景编码生成
            String code;
            boolean res = true;
            while (res) {
                String orderCodesj = String.valueOf(snowflakeIdWorker.nextId());
                code = String.valueOf(stfBusinessTypeEntity.getParentId()).subSequence(0, 2) + orderCodesj.substring(orderCodesj.length() - 5);
                res = repeatName(stfBusinessTypeEntity);
                stfBusinessTypeEntity.setCode(code);
            }
            this.save(stfBusinessTypeEntity);
        } else {
            checkRepeat(stfBusinessTypeEntity);
            this.save(stfBusinessTypeEntity);
        }
        // 插入字典值
        SysDictItemDTO sysDictItemDTO = new SysDictItemDTO();
        sysDictItemDTO.setDictCode("ORDER_TYPE_ID");
        sysDictItemDTO.setName(stfBusinessTypeEntity.getName());
        sysDictItemDTO.setOrderNum(0);
        sysDictItemDTO.setRemark("");
        sysDictItemDTO.setStatus(0);
        sysDictItemDTO.setValue(stfBusinessTypeEntity.getCode());
        sysDictItemDTO.setAppId("0");
        R r = dictClient.add(sysDictItemDTO);
        if (r.getCode() != 200) {
            throw new RuntimeException(r.getMsg());
        }
        // 新增成功后，将数据同步到流程平台
        // 此处获取到父节点中tenantId，作为流程平台的父节点ID
        try {
            Integer parentId = stfBusinessTypeEntity.getParentId();
            StfBusinessTypeEntity entity = getByIdWithDp(parentId);
            stfBusinessTypeEntity.setParentId(Integer.parseInt(entity.getTenantId()));
            R result = bwpOperDockingClient.saveBwpBusiType(JSONObject.toJSONString(stfBusinessTypeEntity));
            // ``````````````````````````````````````重新设置parentId```````````````````````````````````````
            stfBusinessTypeEntity.setParentId(parentId);
            stfBusinessTypeEntity.setTenantId(result.getData().toString());
            updateByIdWithDp(stfBusinessTypeEntity);
        } catch (Exception e) {
            // TODO
        }

        return R.success(stfBusinessTypeEntity.getCode());
    }

    public boolean repeatName(StfBusinessTypeEntity stfBusinessTypeEntity) {
        LambdaQueryWrapper<StfBusinessTypeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(StringUtils.isNotBlank(stfBusinessTypeEntity.getId()), StfBusinessTypeEntity::getId, stfBusinessTypeEntity.getId())
                .and(wrapper -> wrapper
//                        .eq(StfBusinessTypeEntity::getName, stfBusinessTypeEntity.getName())
//                        .eq(StfBusinessTypeEntity::getName, stfBusinessTypeEntity.getName())
//                        .or()
                        .eq(StfBusinessTypeEntity::getCode, stfBusinessTypeEntity.getCode()));
        return count(queryWrapper) > 0;
    }


    @Override
    public List<String> getBusinessTypeByamId(String amId) {
        LambdaQueryWrapper<StfBusinessTypeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(StfBusinessTypeEntity::getId).eq(StfBusinessTypeEntity::getAmId, amId)
                .eq(StfBusinessTypeEntity::getLeafNode, "Y");
        List<StfBusinessTypeEntity> list = this.listWithDp(queryWrapper);
        List<String> listIds = new ArrayList<>();
        for (StfBusinessTypeEntity businessTypeEntity : list) {
            listIds.add(String.valueOf(businessTypeEntity.getId()));
        }
        return listIds;
    }

    private void checkRepeat(StfBusinessTypeEntity stfBusinessTypeEntity) {
        boolean repeat = repeatGlobal(StfBusinessTypeEntity::getId, stfBusinessTypeEntity.getId(), StfBusinessTypeEntity::getCode, stfBusinessTypeEntity.getCode());
        if (repeat) {
            throw new GlobalException(String.format("该业务类型编码重复：%s已创建", stfBusinessTypeEntity.getCode()));
        }
    }

}
